package com.alogic.together2.service;

import java.io.IOException;

import com.alogic.together2.TogetherConstants;
import com.anysoft.util.Settings;
import com.anysoft.webloader.HttpClientTool;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;

import com.alogic.auth.Constants;
import com.alogic.auth.CookieManager;
import com.alogic.auth.Session;
import com.alogic.auth.SessionManager;
import com.alogic.auth.SessionManagerFactory;
import com.alogic.together2.TogetherServiceDescription;
import com.alogic.xscript.LogicletContext;
import com.alogic.xscript.Script;
import com.alogic.xscript.doc.XsObject;
import com.alogic.xscript.doc.json.JsonObject;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import com.logicbus.backend.AbstractServant;
import com.logicbus.backend.Context;
import com.logicbus.backend.message.JsonMessage;
import com.logicbus.backend.message.JsonRawMessage;
import com.logicbus.backend.server.http.HttpContext;
import com.logicbus.models.servant.ServiceDescription;

/**
 * 用于做重定向的Servant
 * 
 * @author yyduan
 * @version 1.6.11.59 [20180911 duanyy] <br>
 * - 使用新的ServantLogicletContext类; <br>
 * 
 * @version 1.6.12.11 [20181206 duanyy] <br>
 * - 可增加session和cookie支持 <br>
 *
 * @version 1.6.12.39 [20190725] <br>
 * - 增加$privilege上下文变量 <br>
 *
 * @version 1.6.14.5 [20210413 duanyy] <br>
 * - 字符串常量使用静态变量 <br>
 */
public class RedirectServant extends AbstractServant implements TogetherConstants {
	protected Script script = null;
	protected String service;
	protected String privilege;
	protected HttpClientTool clientTool = null;
	
	@Override
	protected void onDestroy() {
		
	}

	@Override
	protected void onCreate(ServiceDescription sd) {
		service = sd.getPath();
		privilege = sd.getPrivilege();
		if (sd instanceof TogetherServiceDescription){
			script = ((TogetherServiceDescription)sd).getScript();
		}else{
			Properties p = sd.getProperties();
			String bootstrap = PropertiesConstants.getString(p,BOOTSTRAP,"",true);
			if (StringUtils.isEmpty(bootstrap)){
				String config = PropertiesConstants.getString(p,SCRIPT,"");
				if (StringUtils.isNotEmpty(config)){
					script = Script.create(config, p);
				}
			}else{
				String config = PropertiesConstants.getString(p,SCRIPT,"");
				if (StringUtils.isNotEmpty(config)){
					script = Script.create(bootstrap, config, p);
				}
			}
		}

		clientTool = Settings.getToolkit(HttpClientTool.class);
	}

	@Override
	protected int onJson(Context ctx)  {
		if (script != null){
			JsonRawMessage msg = (JsonRawMessage) ctx.asMessage(JsonRawMessage.class);
			HttpContext httpCtx = (HttpContext)ctx;
			SessionManager sm = SessionManagerFactory.getDefault();
			Session session = sm.getSession(httpCtx.getRequest(),httpCtx.getResponse(),true);
			CookieManager cm = new CookieManager.Default(sm, httpCtx.getRequest(), httpCtx.getResponse());			
			LogicletContext logicletContext = new Context.ServantLogicletContext(ctx);

			try {
				logicletContext.setObject(ID_CONTEXT, ctx);
				logicletContext.SetValue(ID_SERVICE, service);
				logicletContext.SetValue(ID_PRIVILEGE,StringUtils.isEmpty(privilege)?service:privilege);
				logicletContext.setObject(Constants.ID_SESSION, session);
				logicletContext.setObject(Constants.ID_COOKIES, cm);					
				XsObject doc = new JsonObject(ROOT,msg.getRoot());
				script.execute(doc,doc,logicletContext, null);
			}finally{
				logicletContext.removeObject(ID_CONTEXT);
				logicletContext.removeObject(Constants.ID_SESSION);
				logicletContext.removeObject(Constants.ID_COOKIES);						
				String keyword = logicletContext.GetValue(ID_KEYWORD, "");
				if (StringUtils.isNotEmpty(keyword)){
					ctx.setKeyword(keyword);
				}				
				String redirectUrl = logicletContext.GetValue(ID_REDIRECT,"");
				if (StringUtils.isNotEmpty(redirectUrl) && ctx instanceof HttpContext){
					HttpContext httpContext = (HttpContext)ctx;					
					try {
						clientTool.sendRedirect(httpContext.getResponse(),redirectUrl);
					} catch (IOException e) {
						logger.error(ExceptionUtils.getStackTrace(e));
					}
				}
			}
		}else{
			ctx.asMessage(JsonMessage.class);
		}
		return 0;
	}
}
